/**
 * 定时器管理辅助类
 * 用于统一管理页面中的定时器和延时操作
 * 避免内存泄漏和性能问题
 */

// 页面级定时器管理映射表
const pageTimers = new Map();

/**
 * 设置页面关联的定时器
 * @param {Page} pageInstance 页面实例
 * @param {string} timerKey 定时器标识键
 * @param {number} timerId 定时器ID
 */
function setPageTimer(pageInstance, timerKey, timerId) {
  if (!pageInstance || !pageInstance.__wxExparserNodeId__) {
    console.error('无效的页面实例');
    return;
  }

  const pageId = pageInstance.__wxExparserNodeId__;
  if (!pageTimers.has(pageId)) {
    pageTimers.set(pageId, new Map());
    
    // 自动注入清理方法
    _injectCleanupHooks(pageInstance);
  }
  
  const timers = pageTimers.get(pageId);
  timers.set(timerKey, timerId);
}

/**
 * 获取页面关联的定时器ID
 * @param {Page} pageInstance 页面实例
 * @param {string} timerKey 定时器标识键
 * @returns {number|null} 定时器ID或null
 */
function getPageTimer(pageInstance, timerKey) {
  if (!pageInstance || !pageInstance.__wxExparserNodeId__) return null;
  
  const pageId = pageInstance.__wxExparserNodeId__;
  if (!pageTimers.has(pageId)) return null;
  
  const timers = pageTimers.get(pageId);
  return timers.get(timerKey) || null;
}

/**
 * 清除页面特定定时器
 * @param {Page} pageInstance 页面实例
 * @param {string} timerKey 定时器标识键
 */
function clearPageTimer(pageInstance, timerKey) {
  if (!pageInstance || !pageInstance.__wxExparserNodeId__) return;
  
  const pageId = pageInstance.__wxExparserNodeId__;
  if (!pageTimers.has(pageId)) return;
  
  const timers = pageTimers.get(pageId);
  const timerId = timers.get(timerKey);
  
  if (timerId) {
    clearTimeout(timerId);
    clearInterval(timerId);
    timers.delete(timerKey);
  }
}

/**
 * 清除页面所有定时器
 * @param {Page} pageInstance 页面实例
 */
function clearAllPageTimers(pageInstance) {
  if (!pageInstance || !pageInstance.__wxExparserNodeId__) return;
  
  const pageId = pageInstance.__wxExparserNodeId__;
  if (!pageTimers.has(pageId)) return;
  
  const timers = pageTimers.get(pageId);
  for (const timerId of timers.values()) {
    clearTimeout(timerId);
    clearInterval(timerId);
  }
  
  timers.clear();
}

/**
 * 安全设置定时器，自动关联到页面实例
 * @param {Page} pageInstance 页面实例
 * @param {string} timerKey 定时器标识键
 * @param {Function} callback 回调函数
 * @param {number} delay 延迟时间(毫秒)
 * @returns {number} 定时器ID
 */
function setPageTimeout(pageInstance, timerKey, callback, delay) {
  // 先清除同名定时器
  clearPageTimer(pageInstance, timerKey);
  
  // 设置新定时器 - 直接使用原生setTimeout
  const timerId = setTimeout(() => {
    // 执行回调
    callback();
    // 自动从管理列表中移除
    clearPageTimer(pageInstance, timerKey);
  }, delay);
  
  // 记录定时器
  setPageTimer(pageInstance, timerKey, timerId);
  
  return timerId;
}

/**
 * 安全设置循环定时器，自动关联到页面实例
 * @param {Page} pageInstance 页面实例
 * @param {string} timerKey 定时器标识键
 * @param {Function} callback 回调函数
 * @param {number} interval 间隔时间(毫秒)
 * @returns {number} 定时器ID
 */
function setPageInterval(pageInstance, timerKey, callback, interval) {
  // 先清除同名定时器
  clearPageTimer(pageInstance, timerKey);
  
  // 设置新定时器 - 直接使用原生setInterval
  const timerId = setInterval(callback, interval);
  
  // 记录定时器
  setPageTimer(pageInstance, timerKey, timerId);
  
  return timerId;
}

/**
 * 为页面实例注入自动清理钩子
 * @private
 * @param {Page} pageInstance 页面实例
 */
function _injectCleanupHooks(pageInstance) {
  const pageId = pageInstance.__wxExparserNodeId__;
  
  // 保存原始生命周期方法
  const originalOnHide = pageInstance.onHide;
  const originalOnUnload = pageInstance.onUnload;
  
  // 重写onHide
  pageInstance.onHide = function() {
    // 执行原始onHide
    if (originalOnHide) {
      originalOnHide.call(this);
    }
    
    // 清理所有interval类型定时器
    const timers = pageTimers.get(pageId);
    if (timers) {
      for (const [key, timerId] of timers.entries()) {
        if (key.startsWith('interval_')) {
          clearInterval(timerId);
          timers.delete(key);
        }
      }
    }
  };
  
  // 重写onUnload
  pageInstance.onUnload = function() {
    // 执行原始onUnload
    if (originalOnUnload) {
      originalOnUnload.call(this);
    }
    
    // 清理所有定时器
    clearAllPageTimers(pageInstance);
    pageTimers.delete(pageId);
  };
}

module.exports = {
  setTimeout: setPageTimeout,
  setInterval: setPageInterval,
  clearPageTimer,
  clearAllPageTimers,
  getPageTimer
}; 